package Server;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;

import General.ClientEventInterface;
import General.MainShipQuoterServiceInterface;
import General.Product;
import General.QuoteInterface;
import General.ShipQuoterServiceInterface;

public class MainShipQuoterService extends UnicastRemoteObject implements MainShipQuoterServiceInterface {
	
	private static final long serialVersionUID = 1L;
	private SubServerService fSubServerService;
	private HashMap<Integer, ShipQuoterServiceInterface> fSubServerQuoters;

	public MainShipQuoterService(SubServerService	subServerRegistry) throws RemoteException {
		super();
		fSubServerService = subServerRegistry;
		fSubServerQuoters = new HashMap<Integer, ShipQuoterServiceInterface>();
	}

	public QuoteInterface quote(Product product) throws RemoteException {
		return fSubServerService.getNextServer().quote(product);
	}

	public boolean requestForShipping(Product product, ClientEventInterface clientNotificator) throws RemoteException {
		// Check preconditions
		if (this.checkConditions(product)) {
			ShipQuoterServiceInterface subServer = fSubServerService.getNextServer();
			fSubServerQuoters.put(product.getId(), subServer);
			return subServer.requestForShipping(product, clientNotificator);
		} else {
			return false;
		}
	}

	public int getState(int productId) throws RemoteException {
		if (fSubServerQuoters.containsKey(productId)) {
			return fSubServerQuoters.get(productId).getState(productId);
		}
		return 0;
	}
	
	private boolean checkConditions(Product product) {
		// Air-priority not possible for goods that weigh more than 100 kg
		if ((product.getfShippingType() == Product.AIR_PRIORITY) && (product.getWeight() > 100)) {
			return false;
		}
		
		// Air-priority not possible for hazardous goods
		if ((product.getfShippingType() == Product.AIR_PRIORITY) && (product.isfHazardous())) {
			return false;
		}
		
		// Check addresses
		if ((!this.checkAddress(product.getfSourceAddress())) || (!this.checkAddress(product.getfDestinationAddress()))) {
			return false;
		}
		
		return true;
	}
	
	private boolean checkAddress(String address) {
		// Mock implementation of database which checks address validity
		return true;
	}

}
